home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / mail / smailsr2.lha / SMail / src / RCS / headers.c,v < prev    next >
Encoding:
Text File  |  1993-11-30  |  30.3 KB  |  1,569 lines

  1. head    2.3;
  2. access;
  3. symbols
  4.     C_2:2.3
  5.     C_1:1.14;
  6. locks; strict;
  7. comment    @ * @;
  8.  
  9.  
  10. 2.3
  11. date    93.11.28.16.00.27;    author Aussem;    state Exp;
  12. branches;
  13. next    2.2;
  14.  
  15. 2.2
  16. date    93.11.25.19.47.53;    author Aussem;    state Exp;
  17. branches;
  18. next    2.1;
  19.  
  20. 2.1
  21. date    93.11.23.19.58.39;    author Aussem;    state Exp;
  22. branches;
  23. next    1.16;
  24.  
  25. 1.16
  26. date    93.11.21.22.25.21;    author Aussem;    state Exp;
  27. branches;
  28. next    1.15;
  29.  
  30. 1.15
  31. date    93.11.21.22.05.12;    author Aussem;    state Exp;
  32. branches;
  33. next    1.14;
  34.  
  35. 1.14
  36. date    93.11.13.23.13.02;    author Aussem;    state Exp;
  37. branches;
  38. next    1.13;
  39.  
  40. 1.13
  41. date    93.11.06.16.02.16;    author Aussem;    state Exp;
  42. branches;
  43. next    1.12;
  44.  
  45. 1.12
  46. date    93.11.05.22.51.53;    author Aussem;    state Exp;
  47. branches;
  48. next    1.11;
  49.  
  50. 1.11
  51. date    93.11.05.22.22.13;    author Aussem;    state Exp;
  52. branches;
  53. next    1.10;
  54.  
  55. 1.10
  56. date    93.10.28.23.14.01;    author Aussem;    state Exp;
  57. branches;
  58. next    1.9;
  59.  
  60. 1.9
  61. date    93.10.28.22.05.26;    author Aussem;    state Exp;
  62. branches;
  63. next    1.8;
  64.  
  65. 1.8
  66. date    93.10.22.00.27.53;    author Aussem;    state Exp;
  67. branches;
  68. next    1.7;
  69.  
  70. 1.7
  71. date    93.10.17.18.44.20;    author Aussem;    state Exp;
  72. branches;
  73. next    1.6;
  74.  
  75. 1.6
  76. date    93.10.10.21.05.46;    author Aussem;    state Exp;
  77. branches;
  78. next    1.5;
  79.  
  80. 1.5
  81. date    93.10.10.19.32.34;    author Aussem;    state Exp;
  82. branches;
  83. next    1.4;
  84.  
  85. 1.4
  86. date    93.09.18.20.23.05;    author Aussem;    state Exp;
  87. branches;
  88. next    1.3;
  89.  
  90. 1.3
  91. date    93.09.18.16.47.47;    author Aussem;    state Exp;
  92. branches;
  93. next    1.2;
  94.  
  95. 1.2
  96. date    93.09.11.01.42.43;    author Aussem;    state Exp;
  97. branches;
  98. next    1.1;
  99.  
  100. 1.1
  101. date    93.09.08.16.27.13;    author Aussem;    state Exp;
  102. branches;
  103. next    ;
  104.  
  105.  
  106. desc
  107. @analyse and setup the header
  108. @
  109.  
  110.  
  111. 2.3
  112. log
  113. @dateline is now global
  114. dateline will be set to the Date: header of the mail
  115.  if smail is rmail mode
  116. @
  117. text
  118. @/*
  119.  *  headers.c
  120.  *
  121.  *  message spooing, header and address parsing and completion
  122.  *  functions for smail/rmail
  123.  *
  124.  * This program is free software; you can redistribute it and/or
  125.  * modify it under the terms of the GNU General Public License as
  126.  * published by the Free Software Foundation; either version 2 of
  127.  * the License, or (at your option) any later version.
  128.  *
  129.  * This program is distributed in the hope that it will be useful,
  130.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  131.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  132.  * General Public License for more details.
  133.  *
  134.  * You should have received a copy of the GNU General Public License
  135.  * along with this program; if not, write to the Free Software
  136.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  137.  *
  138.  * $Log: headers.c,v $
  139.  * Revision 2.2  1993/11/25  19:47:53  Aussem
  140.  * message id is now unique (uulib:seq is used for this)
  141.  *
  142.  * Revision 2.1  1993/11/23  19:58:39  Aussem
  143.  * Version 2.0 check in
  144.  *
  145.  * Revision 1.16  1993/11/21  22:25:21  Aussem
  146.  * 2.nd try to improve the % handling
  147.  *
  148.  * Revision 1.15  1993/11/21  22:05:12  Aussem
  149.  * the handling of %-address improved
  150.  *
  151.  * Revision 1.14  1993/11/13  23:13:02  Aussem
  152.  * MAXLINE inserted
  153.  *
  154.  * Revision 1.13  1993/11/06  16:02:16  Aussem
  155.  * smail does not look in rmail mode in the mailheader
  156.  *
  157.  * Revision 1.12  1993/11/05  22:51:53  Aussem
  158.  * Return-Receipt-To: recognition now works again
  159.  *
  160.  * Revision 1.11  1993/11/05  22:22:13  Aussem
  161.  * Return-Receipt-To: recognition now works
  162.  *
  163.  * Revision 1.10  1993/10/28  23:14:01  Aussem
  164.  * space on right of return-receipt headers forgotten
  165.  *
  166.  * Revision 1.9  1993/10/28  22:05:26  Aussem
  167.  * comments from return-receipt removed
  168.  *
  169.  * Revision 1.8  1993/10/22  00:27:53  Aussem
  170.  * user%site%site.do.main@@sub.do.main
  171.  * and
  172.  * sub.do.main!site.do.main%site%user
  173.  * addresses are now supported
  174.  *
  175.  * Revision 1.7  1993/10/17  18:44:20  Aussem
  176.  * -f argument is now really used
  177.  * smail does not stop on a single dot on a line anymore
  178.  *
  179.  * Revision 1.6  1993/10/10  21:05:46  Aussem
  180.  * continuation lines and whites spaces are now handled in the
  181.  * right way
  182.  *
  183.  * Revision 1.5  1993/10/10  19:32:34  Aussem
  184.  * Bcc: lines are now supported
  185.  *
  186.  * Revision 1.4  1993/09/18  20:23:05  Aussem
  187.  * the cc line can now be parsed from cmdline and from file
  188.  *
  189.  * Revision 1.3  1993/09/18  16:47:47  Aussem
  190.  * insert GNU license text in the header
  191.  *
  192.  * Revision 1.2  1993/09/11  01:42:43  Aussem
  193.  * To: lines will bei insert from mailbody AND cmdline
  194.  * EnforcerHits while generation the Cc: line removed
  195.  *
  196.  * Revision 1.1  1993/09/08  16:27:13  Aussem
  197.  * Initial revision
  198.  *
  199.  *
  200.  */
  201.  
  202. static char     *rcsid="$Id: headers.c,v 2.2 1993/11/25 19:47:53 Aussem Exp Aussem $";
  203.  
  204. # include    <stdio.h>
  205. # include    <stdlib.h>
  206. # include    <sys/types.h>
  207. # include    <time.h>
  208. # include    <ctype.h>
  209. # include    "defs.h"
  210.  
  211. extern enum edebug debug;    /* how verbose we are         */
  212. extern char hostname[];        /* */
  213. extern char hostdomain[];    /* */
  214. extern char *spoolfile;        /* file name of spooled message */
  215. extern FILE *spoolfp;        /* file ptr  to spooled message */
  216. extern int spoolmaster;        /* set if creator of spoolfile  */
  217. extern time_t now;        /* time                */
  218. extern char nows[], arpanows[];    /* time strings            */
  219. extern struct tm *gmt, *loc;    /* time structs            */
  220. extern char *from_addr;        /* replacement fromaddr with -f */
  221. extern char *subject;     /* replacement subject with -s */
  222. extern char *realname;
  223. extern int cc_index;
  224. extern int bcc_index;
  225. extern int receipt;
  226. extern FILE *mystdin;
  227. extern int asrmail;
  228.  
  229. char  return_receipt[SMLBUF]="";
  230. char  dateline[SMLBUF]="";
  231.  
  232. static char toline[SMLBUF];
  233. static char fromline[SMLBUF];
  234. static char midline[SMLBUF];
  235. static char subjectline[SMLBUF];
  236. static char ccline[SMLBUF]="";
  237. static char *ieof = "NOTNULL";
  238.  
  239. struct reqheaders {
  240.     char *name;
  241.     char *field;
  242.     char have;
  243. };
  244.  
  245. static struct reqheaders reqtab[] = {
  246.     "Message-Id:"    ,    midline        ,    'N'    ,
  247.     "Date:"        ,    dateline    ,    'N'    ,
  248.     "From:"        ,    fromline    ,    'N'    ,
  249.     "To:"        ,    toline        ,    'N'    ,
  250.     "Cc:"        ,    NULL        ,    'N'    ,
  251.     "Bcc:"        ,    NULL        ,    'N'    ,
  252.     "Subject:"    ,    subjectline        ,    'N'    ,
  253.     NULL         ,    NULL        ,    'N'
  254. };
  255.  
  256.  
  257. /*
  258. **
  259. ** parse(): parse <address> into <domain, user, form>.
  260. **
  261. **     input        form
  262. **    -----        ----
  263. **    user        LOCAL
  264. **    domain!user    DOMAIN
  265. **    user@@domain    DOMAIN
  266. **    @@domain,address    LOCAL    (just for sendmail)
  267. **    host!address    UUCP
  268. **
  269. */
  270.  
  271. enum eform
  272. parse(address, domain, user)
  273. char *address;        /* input address     */
  274. char *domain;        /* output domain     */
  275. char *user;        /* output user         */
  276. {
  277.     int parts;
  278.     char *partv[MAXPATH];                /* to crack address */
  279.  
  280. /*
  281. **  If this is route address form @@domain_a,@@domain_b:user@@domain_c, ...
  282. */
  283.  
  284.     if(*address == '@@')
  285. #ifdef SENDMAIL
  286. /*
  287. **  hand it to sendmail
  288. */
  289.     {
  290.         goto local;
  291.     }
  292. #else
  293. /*
  294. **  no sendmail, convert it into a bang path: domain_a!domain_b!domain_c!user
  295. */
  296.     {
  297.         char buf[SMLBUF], *p;
  298.         char t_dom[SMLBUF], t_user[SMLBUF];
  299.  
  300.         (void) strcpy(buf, address+1);        /* elide leading '@@' */
  301.  
  302.         for(p=buf; *p != '\0' ; p++) {    /* search for ',' or ':' */
  303.             if(*p == ':') {        /* reached end of route */
  304.                 break;
  305.             }
  306.             if(*p == ',') {        /* elide ','s */
  307.                 (void) strcpy(p, p+1);
  308.             }
  309.             if(*p == '@@') {        /* convert '@@' to '!' */
  310.                 *p = '!';
  311.             }
  312.         }
  313.  
  314.         if(*p != ':') {    /* bad syntax - punt */
  315.             goto local;
  316.         }
  317.         *p = '\0';
  318.  
  319.         if(parse(p+1, t_dom, t_user) != LOCAL) {
  320.             (void) strcat(buf, "!");
  321.             (void) strcat(buf, t_dom);
  322.         }
  323.         (void) strcat(buf, "!");
  324.         (void) strcat(buf, t_user);
  325.  
  326.         /* munge the address (yuk)
  327.         ** it's OK to copy into 'address', because the machinations
  328.         ** above don't increase the string length of the address.
  329.         */
  330.  
  331.         (void) strcpy(address, buf);
  332.  
  333.         /* re-parse the address */
  334.         return(parse(address, domain, user));
  335.     }
  336. #endif
  337.  
  338. /*
  339. **    user%site%site.do.main@@sub.do.main
  340. ** -> sub.do.main!site.do.main!site!user
  341. **
  342. **    sub.do.main!site.do.main%site%user
  343. ** -> sub.do.main!site.do.main!site!user
  344. */
  345. if(strchr(address,'%'))
  346.     {
  347.    register int i;
  348.    int flag=0;
  349.    char *p,*start,*backup=NULL;
  350.  
  351.    /* search the first ! sign left from the % sign */
  352.    for(start=strchr(address,'%');start>address;start--)
  353.       if(*start=='!'){flag=1;break;}
  354.  
  355.    /* use only the right part of the ! sign (if there exists one) */
  356.    if(flag)
  357.        backup=strdup(start+1);
  358.    else
  359.        backup=strdup(address);
  360.  
  361.       parts = ssplit(backup, '@@', partv);
  362.    if(parts>1)
  363.        {
  364.       /* we have a @@ so we split user%domain1@@domain2 to domain2!domain1!user */
  365.         strcpy(domain, partv[1]);
  366.         strncpy(user, partv[0], partv[1]-partv[0]-1);
  367.         user[partv[1]-partv[0]-1] = '\0';
  368.         strcpy(backup,domain);
  369.           parts = ssplit(user, '%', partv);
  370.  
  371.        for(i=0;i<parts;i++)
  372.            {
  373.           p=strchr(partv[parts-i-1],'%');
  374.           if(p)    *p='\0';
  375.             strcat(backup,"!");
  376.            strcat(backup,partv[parts-i-1]);
  377.            }
  378.        }
  379.    else
  380.        {
  381.       /* we have no @@ sign so change user%domain to domain!user */
  382.          parts = ssplit(backup, '%', partv);
  383.         (void) strcpy(domain, partv[parts-1]);
  384.         (void) strncpy(user, partv[0], partv[parts-1]-partv[0]-1);
  385.         user[partv[parts-1]-partv[0]-1] = '\0';
  386.         strcpy(backup,domain);
  387.         strcat(backup,"!");
  388.         strcat(backup,user);
  389.        }
  390.  
  391.    /* tackon on the !-part (if there exists one) */
  392.    if(flag)
  393.        {*(start+1)='\0';strcat(address,backup);}
  394.    else
  395.        strcpy(address,backup);
  396.  
  397.    /* free the backup buffer */
  398.    if(backup)free(backup);
  399.     }
  400. /*
  401. **  Try splitting at @@.  If it works, this is user@@domain, form DOMAIN.
  402. **  Prefer the righthand @@ in a@@b@@c.
  403. */
  404.     if ((parts = ssplit(address, '@@', partv)) >= 2) {
  405.         (void) strcpy(domain, partv[parts-1]);
  406.         (void) strncpy(user, partv[0], partv[parts-1]-partv[0]-1);
  407.         user[partv[parts-1]-partv[0]-1] = '\0';
  408.         return (DOMAIN);
  409.     }
  410.  
  411. /*
  412. **  Try splitting at !. If it works, see if the piece before the ! has
  413. **  a . in it (domain!user, form DOMAIN) or not (host!user, form UUCP).
  414. */
  415.     if (ssplit(address, '!', partv) > 1) {
  416.         (void) strcpy(user, partv[1]);
  417.         (void) strncpy(domain, partv[0], partv[1]-partv[0]-1);
  418.         domain[partv[1]-partv[0]-1] = '\0';
  419.  
  420.         if((parts = ssplit(domain, '.', partv)) < 2) {
  421.             return(UUCP);
  422.         }
  423.  
  424.         if(partv[parts-1][0] == '\0') {
  425.             partv[parts-1][-1] = '\0'; /* strip trailing . */
  426.         }
  427.         return (DOMAIN);
  428.     }
  429. /* 
  430. **  Done trying.  This must be just a user name, form LOCAL.
  431. */
  432. local:
  433.     (void) strcpy(user, address);
  434.     (void) strcpy(domain, "");
  435.     return(LOCAL);                /* user */
  436. }
  437.  
  438. build(domain, user, form, result)
  439. char *domain;
  440. char *user;
  441. enum eform form;
  442. char *result;
  443. {
  444.     switch((int) form) {
  445.     case LOCAL:
  446.         (void) sprintf(result, "%s", user); 
  447.         break;
  448.     case UUCP:
  449.         (void) sprintf(result, "%s!%s", domain, user);
  450.         break;
  451.     case DOMAIN:
  452.         (void) sprintf(result, "%s@@%s", user, domain);
  453.         break;
  454.     }
  455. }
  456.  
  457. /*
  458. **  ssplit(): split a line into array pointers.
  459. **
  460. **  Each pointer wordv[i] points to the first character after the i'th 
  461. **  occurence of c in buf.  Note that each wordv[i] includes wordv[i+1].
  462. **
  463. */
  464.  
  465. ssplit(buf, c, ptr)
  466. register char *buf;        /* line to split up         */
  467. char c;                /* character to split on    */
  468. char **ptr;            /* the resultant vector        */
  469. {
  470.         int count = 0;
  471.         int wasword = 0;
  472.  
  473.         for(; *buf; buf++) {
  474.         if (!wasword) {
  475.             count++;
  476.             *ptr++ = buf;
  477.         }
  478.         wasword = (c != *buf);
  479.         }
  480.     if (!wasword) {
  481.         count++;
  482.         *ptr++ = buf;
  483.     }
  484.         *ptr = NULL;
  485.         return(count);
  486. }
  487.  
  488. /*
  489. ** Determine whether an address is a local address
  490. */
  491.  
  492. islocal(addr, domain, user)
  493. char *addr, *domain, *user;
  494. {
  495.         enum eform form;
  496.         extern char hostuucp[];
  497.  
  498.         /*
  499.         ** parse the address
  500.         */
  501.  
  502.         form = parse(addr, domain, user);
  503.  
  504.         if((form == LOCAL)            /* user */
  505.         ||(strcmpic(domain, hostdomain) == 0)    /* user@@hostdomain */
  506.         ||(strcmpic(domain, hostname)   == 0)    /* user@@hostname */
  507. #ifdef DOMGATE
  508.         ||(strcmpic(domain, &MYDOM[0]) == 0)    /* user@@MYDOM w/ dot */
  509.         ||(strcmpic(domain, &MYDOM[1]) == 0)    /* user@@MYDOM no dot */
  510. #endif
  511.         ||(strcmpic(domain, hostuucp)   == 0)) {/* user@@hostuucp */
  512.             return(1);
  513.         }
  514.         return(0);
  515. }
  516.  
  517. /*
  518.  *
  519.  */
  520. void
  521. checkheader(char *buf)
  522. {
  523. const char receipt[]="Return-Receipt-To:";
  524. const size_t receipt_len=strlen(receipt);
  525.  
  526. if(strncmpic(buf,(char *)receipt,receipt_len)==0)
  527.     {
  528.     char *r=buf+receipt_len;
  529.  
  530.    for(;*r==' ';r++);
  531.    strcpy(return_receipt,&r[0]);
  532.    r=strchr(return_receipt,' ');
  533.    if(r)
  534.        *r='\0';
  535.    r=strchr(return_receipt,'\n');
  536.    if(r)
  537.        *r='\0';
  538.    strip_comments(return_receipt);
  539.     }
  540. }
  541.  
  542. /*
  543. ** spool - message spooling module
  544. **
  545. ** (1) get dates for headers, etc.
  546. ** (2) if the message is on the standard input (no '-f')
  547. **     (a) create a temp file for spooling the message.
  548. **     (b) collapse the From_ headers into a path.
  549. **     (c) if the mail originated locally, then
  550. **         (i) establish default headers
  551. **        (ii) scan the message headers for required header fields
  552. **       (iii) add any required message headers that are absent
  553. **     (d) copy rest of the message to the spool file
  554. **     (e) close the spool file
  555. ** (3) open the spool file for reading
  556. */
  557.  
  558. void
  559. spool(argc, argv)
  560. int argc;
  561. char **argv;
  562. {
  563.     static char *tmpf = "T:";    /* temp file name */
  564.     char buf[SMLBUF];
  565.     static char splbuf[SMLBUF];
  566.     char from[SMLBUF], domain[SMLBUF], user[SMLBUF];
  567.    int flag=0;
  568.  
  569.     /*
  570.     ** if the mail has already been spooled by
  571.     ** a previous invocation of smail don't respool.
  572.     ** check the file name to prevent things like
  573.     ** rmail -f /etc/passwd badguy@@dreadfuldomain
  574.     */
  575.  
  576.     if((spoolfile != NULL)
  577.     && (strnicmp(spoolfile, tmpf, strlen(tmpf)) != 0)) {
  578.         error(EX_TEMPFAIL, "spool: bad file name '%s'\n", spoolfile);
  579.     }
  580.  
  581.     /*
  582.     ** set dates in local, arpa, and gmt forms
  583.     */
  584.     setdates();
  585.  
  586.     /*
  587.     ** If necessary, copy mystdin to a temp file.
  588.     */
  589.  
  590.     if(spoolfile == NULL) {
  591.         spoolfile = strcpy(splbuf, tmpnam(NULL));
  592.  
  593.         if((spoolfp = fopen(spoolfile, "w")) == NULL) {
  594.             error(EX_CANTCREAT, "can't create %s.\n", spoolfile);
  595.         }
  596.  
  597.         spoolmaster = 1;
  598.  
  599.         /*
  600.         ** rline reads the standard input,
  601.         ** collapsing the From_ and >From_
  602.         ** lines into a single uucp path.
  603.         ** first non-from_ line is in buf[];
  604.         */
  605.  
  606.         rline(from, buf);
  607.  
  608.         /*
  609.       ** if we are not rmail (or started as rmail)
  610.         ** if the mail originated here, we parse the header
  611.         ** and add any required headers that are missing.
  612.         */
  613.  
  614.         if(!asrmail && (islocal(from, domain, user) || (from_addr != NULL))) {
  615.             /*
  616.             ** initialize default headers
  617.             */
  618.             def_headers(argc, argv, from);
  619.  
  620.          /*
  621.          ** Return-Receipt-To: check is done in scanheaders()
  622.          */
  623.          flag=1;
  624.             /*
  625.             ** buf has first, non-from_  line
  626.             */
  627.             scanheaders(buf);
  628.             /*
  629.             ** buf has first, non-header line,
  630.             */
  631.  
  632.             compheaders();
  633.  
  634.             if(buf[0] != '\n') {
  635.                 (void) fputs("\n", spoolfp);
  636.             }
  637.         }
  638.  
  639.         /*
  640.         ** now, copy the rest of the letter into the spool file
  641.         ** terminate on either EOF or '^.$'
  642.         */
  643.         while(ieof != NULL) {
  644.          /*
  645.          ** !flag while we are in the header part
  646.          */
  647.          if(!flag && buf[0]=='\n')
  648.            flag=1;
  649.          /*
  650.          ** if we are in the header and we
  651.          ** should reply to Return-Receipt-To:
  652.          ** Whether smail really answers the header
  653.          ** is decided in deliver.c
  654.          */
  655.          if(receipt && !flag)
  656.            checkheader(buf);
  657.          /*
  658.          ** if we are in the header and the dateline
  659.          ** isn't set
  660.          */
  661.          if(!flag && strncmp(buf,"Date:",5)==0)
  662.            strcpy(dateline,buf);
  663.  
  664.             (void) fputs(buf, spoolfp);
  665.             if((fgets(buf, SMLBUF, mystdin) == NULL)
  666.         /*
  667.          **   Don't know whether this right
  668.          **    || (buf[0] == '.' && buf[1] == '\n')
  669.        */
  670.             )
  671.             {
  672.                 ieof = NULL;
  673.             }
  674.         }
  675.  
  676.         /*
  677.         ** close the spool file, and the standard input.
  678.         */
  679.  
  680.         (void) fclose(spoolfp);
  681.         (void) fclose(mystdin);    /* you don't see this too often! */
  682.     }
  683.  
  684.     if((spoolfp = fopen(spoolfile, "r")) == NULL) {
  685.         error(EX_TEMPFAIL, "can't open %s.\n", spoolfile);
  686.     }
  687. }
  688.  
  689. /*
  690. **
  691. **  rline(): collapse From_ and >From_ lines.
  692. **
  693. **  Same idea as the old rmail, but also turns user@@domain to domain!user.
  694. **
  695. */
  696.  
  697. void
  698. rline(from, retbuf)
  699. char *from;
  700. char *retbuf;
  701. {
  702.     int parts;            /* for cracking From_ lines ... */
  703.     char *partv[16];        /* ... apart using ssplit()     */
  704.     char user[SMLBUF];        /* for rewriting user@@host    */
  705.     char domain[SMLBUF];        /* "   "         "              */
  706.     char addr[SMLBUF];        /* "   "         "              */
  707.     enum eform form;    /* "   "         "              */
  708.     char *c;
  709.     int nhops, i;
  710.     char buf[SMLBUF], tmp[SMLBUF], *hop[128], *e, *b;
  711.  
  712.     if(spoolmaster == 0) return;
  713.  
  714.     buf[0] = from[0] = addr[0] = '\0';
  715. /*
  716. **  Read each line until we hit EOF or a line not beginning with "From "
  717. **  or ">From " (called From_ lines), accumulating the new path in from
  718. **  and stuffing the actual sending user (the user name on the last From_
  719. **  line) in addr.
  720. */
  721.     for(;;) {
  722.         (void) strcpy(retbuf, buf);
  723.         if(ieof == NULL) {
  724.             break;
  725.         }
  726.         if((fgets(buf, sizeof(buf), mystdin) == NULL)
  727.       /*
  728.       ** Don't stop at a line with only one dot
  729.         **|| (buf[0] == '.' && buf[1] == '\n')
  730.         */
  731.       ) {
  732.             ieof = NULL;
  733.             break;
  734.         }
  735.         if (strncmp("From ", buf, 5)
  736.             && strncmp(">From ", buf, 6)) {
  737.             break;
  738.         }
  739. /*
  740. **  Crack the line apart using ssplit.
  741. */
  742.         if(c = index(buf, '\n')) {
  743.             *c = '\0';
  744.         }
  745.         parts = ssplit(buf, ' ', partv);
  746. /*
  747. **  Tack host! onto the from argument if "remote from host" is present.
  748. */
  749.  
  750.         if((parts > 3)
  751.         && (strncmp("remote from ", partv[parts-3], 12) == 0)) {
  752.             (void) strcat(from, partv[parts-1]);
  753.             (void) strcat(from, "!");
  754.         }
  755. /*
  756. **  Stuff user name into addr, overwriting the user name from previous
  757. **  From_ lines, since only the last one counts.  Then rewrite user@@host
  758. **  into host!user, since @@'s don't belong in the From_ argument.
  759. */
  760.         if(parts < 2) {
  761.             break;
  762.         } else {
  763.             char *x = partv[1];
  764.             char *q = index(x, ' ');
  765.             if(q != NULL) {
  766.                 *q = '\0';
  767.             }
  768.             (void) strcpy(addr, x);
  769.         }
  770.  
  771.         (void) parse(addr, domain, user);
  772.         if(*domain == '\0') {
  773.             form = LOCAL;
  774.         } else {
  775.             form = UUCP;
  776.         }
  777.  
  778.         build(domain, user, form, addr);
  779.     }
  780. /*
  781. **  Now tack the user name onto the from argument.
  782. */
  783.     (void) strcat(from, addr);
  784. /*
  785. **  If we still have no from argument, we have junk headers, but we try
  786. **  to get the user's name using /etc/passwd.
  787. */
  788.  
  789.     if (from[0] == '\0') 
  790.         {
  791.       if(!from_addr)
  792.           {
  793.             char *login;
  794.  
  795.             if ((login = getloginname()) == NULL)
  796.                  strcpy(from, "nobody");    /* bad news */
  797.                 else
  798.                  strcpy(from, login);
  799.             }
  800.       else
  801.             strcpy(from,from_addr);
  802.         }
  803.     /* split the from line on '!'s */
  804.     nhops = ssplit(from, '!', hop);
  805.  
  806.     for(i = 0; i < (nhops - 1); i++) {
  807.         b = hop[i];
  808.         if(*b == '\0') {
  809.             continue;
  810.         }
  811.         e = hop[i+1];
  812.         e-- ;
  813.         *e = '\0';    /* null terminate each path segment */
  814.         e++;
  815.  
  816. #ifdef HIDDENHOSTS
  817. /*
  818. **  Strip hidden hosts:  anything.hostname.MYDOM -> hostname.MYDOM
  819. */
  820.         for(p = b;(p = index(p, '.')) != NULL; p++) {
  821.             if(strcmpic(hostdomain, p+1) == 0) {
  822.                 (void) strcpy(b, hostdomain);
  823.                 break;
  824.             }
  825.         }
  826. #endif
  827.  
  828. /*
  829. **  Strip useless MYDOM: hostname.MYDOM -> hostname
  830. */
  831.         if(strcmpic(hop[i], hostdomain) == 0) {
  832.             (void) strcpy(hop[i], hostname);
  833.         }
  834.     }
  835.  
  836. /*
  837. **  Now strip out any redundant information in the From_ line
  838. **  a!b!c!c!d    => a!b!c!d
  839. */
  840.  
  841.     for(i = 0; i < (nhops - 2); i++) {
  842.         b = hop[i];
  843.         e = hop[i+1];
  844.         if(strcmpic(b, e) == 0) {
  845.             *b = '\0';
  846.         }
  847.     }
  848. /*
  849. **  Reconstruct the From_ line
  850. */
  851.     tmp[0] = '\0';            /* empty the tmp buffer */
  852.  
  853.     for(i = 0; i < (nhops - 1); i++) {
  854.         if((hop[i][0] == '\0')    /* deleted this hop */
  855.          ||((tmp[0] == '\0')    /* first hop == hostname */
  856.           &&(strcmpic(hop[i], hostname) == 0))) {
  857.             continue;
  858.         }
  859.         (void) strcat(tmp, hop[i]);
  860.         (void) strcat(tmp, "!");
  861.     }
  862.     (void) strcat(tmp, hop[i]);
  863.     (void) strcpy(from, tmp);
  864.     (void) strcpy(retbuf, buf);
  865.     (void) fprintf(spoolfp, "%s\n", from);
  866. }
  867.  
  868. /*
  869.  *
  870.  */
  871. void
  872. scanheaders(buf)
  873. char *buf;
  874. {
  875.     int inheader = 0;
  876.  
  877.     while(ieof != NULL) {
  878.         if(buf[0] == '\n') {
  879.             break; /* end of headers */
  880.         }
  881.  
  882.         /*
  883.         ** header lines which begin with whitespace
  884.         ** are continuation lines
  885.         */
  886.         if((inheader == 0)
  887.         || ((buf[0] != ' ' && buf[0] != '\t'))) {
  888.             /* not a continuation line
  889.             ** check for header
  890.             */
  891.             if(isheader(buf) == 0) {
  892.                 /*
  893.                 ** not a header
  894.                 */
  895.                 break;
  896.             }
  897.             inheader = 1;
  898.             haveheaders(buf);
  899.          /*
  900.          ** if we should reply to Return-Receipt-To:
  901.          ** grep the address line
  902.          ** Whether smail answers the header
  903.          ** is decided in deliver.c
  904.          */
  905.          if(receipt) checkheader(buf);
  906.         }
  907.  
  908.         /* 
  909.        ** ignore continuation lines and white spaces
  910.        ** their will be handled in To:,Cc: nad Bcc: lines
  911.        **
  912.        */
  913.         if(buf[0] == ' ' || buf[0] == '\t')
  914.             buf[0]='\0';
  915.  
  916.         (void) fputs(buf, spoolfp);
  917.         if((fgets(buf, SMLBUF, mystdin) == NULL)
  918.       /*
  919.       ** Don't stop at a line with only one dot
  920.         **|| (buf[0] == '.' && buf[1] == '\n')
  921.         */
  922.       ) {
  923.             ieof = NULL;
  924.         }
  925.     }
  926.  
  927.     if(isheader(buf)) {
  928.         buf[0] = '\0';
  929.     }
  930. }
  931.  
  932. /*
  933. ** complete headers - add any required headers that are not in the message
  934. */
  935. void
  936. compheaders()
  937. {
  938.     struct reqheaders *i;
  939.  
  940.     /*
  941.     ** look at the table of required headers and
  942.     ** add those that are missing to the spooled message.
  943.     */
  944.     for(i = reqtab; i->name != NULL; i++) {
  945.    /* for the cc-line and bcc-line the field ptr is NULL */
  946.         if(i->have != 'Y' && i->field) {
  947.             (void) fprintf(spoolfp, "%s\n", i->field);
  948.         }
  949.     }
  950. }
  951.  
  952. /*
  953. ** look at a string and determine
  954. ** whether or not it is a valid header.
  955. */
  956. isheader(s)
  957. char *s;
  958. {
  959.     char *p;
  960.  
  961.     /*
  962.     ** header field names must terminate with a colon
  963.     ** and may not be null.
  964.     */
  965.     if(((p = index(s, ':')) == NULL) || (s == p)) {
  966.         return(0);
  967.  
  968.     }
  969.     /*
  970.     ** header field names must consist entirely of
  971.     ** printable ascii characters.
  972.     */
  973.     while(s != p) {
  974.        if(!isprint(*s))
  975.             return(0);
  976. /* we have ansi! if((*s < '!') || (*s > '~'))    return(0); */
  977.         s++;
  978.     }
  979.     /*
  980.     ** we hit the ':', so the field may be a header
  981.     */
  982.     return(1);
  983. }
  984.  
  985. /*
  986. ** compare the header field to those in the required header table.
  987. ** if it matches, then mark the required header as being present
  988. ** in the message.
  989. */
  990. haveheaders(s)
  991. char *s;
  992. {
  993.     struct reqheaders *i;
  994.  
  995.     for(i = reqtab; i->name != NULL; i++) {
  996.         if(strncmpic(i->name, s, strlen(i->name)) == 0) {
  997.             if((strncmpic("Subject:", s, 8) == 0)
  998.             && (subject != NULL)) {
  999.                 (void) sprintf(s, "Subject: %s\n", subject);
  1000.             }
  1001.             if((strncmpic("From:", s, 5) == 0)
  1002.             && (from_addr != NULL)) {
  1003.                 (void) sprintf(s, "From: %s\n", from_addr);
  1004.             }
  1005.          /* To: Cc: and Bcc: will be handled differently */
  1006.             if((strncmpic("To:", s, 3) == 0) ||
  1007.             (strncmpic("Bcc:", s, 4) == 0) ||
  1008.             (strncmpic("Cc:", s, 3) == 0))
  1009.                 *s='\0';
  1010.          else
  1011.                 i->have = 'Y';
  1012.             break;
  1013.         }
  1014.     }
  1015. }
  1016.  
  1017. /*
  1018. ** create default headers for the message.
  1019. */
  1020. def_headers(argc, argv, from)
  1021. int argc;
  1022. char **argv;
  1023. char *from;
  1024. {
  1025.     def_to(argc, argv);    /* default To:        */
  1026.     def_date();        /* default Date:    */
  1027.     def_from(from);        /* default From:     */
  1028.     def_mid();        /* default Message-Id:    */
  1029.    def_subject();
  1030. }
  1031.  
  1032. /*
  1033. ** default Date: in arpa format
  1034. */
  1035. def_date()
  1036. {
  1037.     (void) strcpy(dateline, "Date: ");
  1038.     (void) strcat(dateline, arpanows);
  1039. }
  1040.  
  1041. /*
  1042. ** default Message-Id
  1043. **  Message-Id: <yymmddhhmm.AAppppp@@hostdomain>
  1044. **
  1045. **    yy     year
  1046. **    mm     month
  1047. **    dd     day
  1048. **    hh     hour
  1049. **    mm     minute
  1050. ** unique string
  1051. **
  1052. ** date and time are set by GMT
  1053. */
  1054. def_mid()
  1055. {
  1056.     (void) sprintf(midline, "Message-Id: <%02d%02d%02d%02d%02d.%s@@%s>",
  1057.         gmt->tm_year,
  1058.         gmt->tm_mon+1,
  1059.         gmt->tm_mday,
  1060.         gmt->tm_hour,
  1061.         gmt->tm_min,
  1062.         seqtoname (getsequence (1),15),
  1063.         hostdomain);
  1064. }
  1065.  
  1066. /*
  1067. ** default Subject: from cmd-line
  1068. **
  1069. */
  1070. def_subject()
  1071. {
  1072.     if (subject != NULL) {
  1073.         (void) sprintf(subjectline, "Subject: %s", subject);
  1074.         return;
  1075.     }
  1076. }
  1077. /*
  1078. ** default From:
  1079. **  From: user@@hostdomain (Full Name)
  1080. */
  1081. def_from(from)
  1082. char *from;
  1083. {
  1084.     char name[SMLBUF];
  1085.  
  1086.     name[0] = '\0';
  1087.    if(!realname)
  1088.       realname=getrealname(from_addr?from_addr:from);
  1089.    if(realname)
  1090.        strcpy(name,realname);
  1091.  
  1092.     if (from_addr != NULL) {
  1093.         if(name[0] != '\0') {
  1094.             (void) sprintf(fromline,
  1095.                 "From: %s@@%s (%s)", from_addr, hostdomain, name);
  1096.         } else {
  1097.             (void) sprintf(fromline,
  1098.                 "From: %s@@%s", from_addr, hostdomain);
  1099.         }
  1100.         return;
  1101.     }
  1102.  
  1103.     if(name[0] != '\0') {
  1104.         (void) sprintf(fromline,
  1105.             "From: %s@@%s (%s)", from, hostdomain, name);
  1106.     } else {
  1107.         (void) sprintf(fromline,
  1108.             "From: %s@@%s", from, hostdomain);
  1109.     }
  1110. }
  1111.  
  1112. /*
  1113. ** default To:
  1114. **  To: recip1, recip2, ...
  1115. **
  1116. ** lines longer than MAXLINE chars are continued on another line.
  1117. */
  1118. def_to(argc, argv)
  1119. int argc;
  1120. char **argv;
  1121. {
  1122.     int i, n;
  1123.     char *bol;
  1124.  
  1125.    /* if we have bcc-lines in argv donnot 
  1126.       print them in the outgoing mail  */
  1127.    if(bcc_index!=-1)
  1128.        argc=bcc_index;
  1129.  
  1130.     bol = toline;
  1131.     (void) strcpy(bol, "To: ");
  1132.     for(n = i = 0; i < argc; i++) {
  1133.    /* insert the Cc: line */
  1134.       if(i==cc_index)
  1135.           {
  1136.             bol=rindex(toline,',');
  1137.             *bol = '\n';
  1138.             *(bol+1) = '\0';
  1139.             n = 0;
  1140.           strcat(bol,"Cc: ");
  1141.             }
  1142.         (void) strcat(bol, argv[i]);
  1143.  
  1144.         if((index(argv[i], '!') == NULL)
  1145.         && (index(argv[i], '@@') == NULL)) {
  1146.             (void) strcat(bol, "@@");
  1147.             (void) strcat(bol, hostdomain);
  1148.         }
  1149.         if(i+1 < argc) {
  1150.             n = strlen(bol);
  1151.             /* if the line is greater than MAXLINE columns */
  1152.             if(n > MAXLINE) {
  1153.                 (void) strcat(bol, ",\n\t");
  1154.                 bol = bol + strlen(bol);
  1155.                 *bol = '\0';
  1156.                 n = 8;
  1157.             } else {
  1158.                 (void) strcat(bol, ", ");
  1159.             }
  1160.         }
  1161.     }
  1162. }
  1163. @
  1164.  
  1165.  
  1166. 2.2
  1167. log
  1168. @message id is now unique (uulib:seq is used for this)
  1169. @
  1170. text
  1171. @d22 3
  1172. d85 1
  1173. a85 1
  1174. static char     *rcsid="$Id: headers.c,v 2.1 1993/11/23 19:58:39 Aussem Exp Aussem $";
  1175. d113 1
  1176. a116 1
  1177. static char dateline[SMLBUF];
  1178. d540 7
  1179. @
  1180.  
  1181.  
  1182. 2.1
  1183. log
  1184. @Version 2.0 check in
  1185. @
  1186. text
  1187. @d22 3
  1188. d82 1
  1189. a82 1
  1190. static char     *rcsid="$Id: headers.c,v 1.16 1993/11/21 22:25:21 Aussem Exp Aussem $";
  1191. d923 1
  1192. a923 1
  1193. **    ppppp    process-id
  1194. d929 1
  1195. a929 1
  1196.     (void) sprintf(midline, "Message-Id: <%02d%02d%02d%02d%02d.AA%05d@@%s>",
  1197. d935 1
  1198. a935 1
  1199.         getpid(),
  1200. @
  1201.  
  1202.  
  1203. 1.16
  1204. log
  1205. @2.nd try to improve the % handling
  1206. @
  1207. text
  1208. @d22 3
  1209. d79 1
  1210. a79 1
  1211. static char     *rcsid="$Id: headers.c,v 1.15 1993/11/21 22:05:12 Aussem Exp Aussem $";
  1212. @
  1213.  
  1214.  
  1215. 1.15
  1216. log
  1217. @the handling of %-address improved
  1218. @
  1219. text
  1220. @d22 3
  1221. d76 1
  1222. a76 1
  1223. static char     *rcsid="$Id: headers.c,v 1.14 1993/11/13 23:13:02 Aussem Exp Aussem $";
  1224. d238 1
  1225. d255 8
  1226. a262 2
  1227.       for(p=backup;*p!='\0';p++)
  1228.           if(*p=='%')*p='!';
  1229. @
  1230.  
  1231.  
  1232. 1.14
  1233. log
  1234. @MAXLINE inserted
  1235. @
  1236. text
  1237. @d22 3
  1238. d73 1
  1239. a73 1
  1240. static char     *rcsid="$Id: headers.c,v 1.13 1993/11/06 16:02:16 Aussem Exp Aussem $";
  1241. d219 12
  1242. a230 1
  1243.    char *p;
  1244. d232 1
  1245. a232 1
  1246.       parts = ssplit(address, '@@', partv);
  1247. d238 1
  1248. a238 1
  1249.         strcpy(address,domain);
  1250. d245 2
  1251. a246 2
  1252.             strcat(address,"!");
  1253.            strcat(address,partv[parts-i-1]);
  1254. d251 1
  1255. a251 1
  1256.       for(p=address;*p!='\0';p++)
  1257. d254 9
  1258. @
  1259.  
  1260.  
  1261. 1.13
  1262. log
  1263. @smail does not look in rmail mode in the mailheader
  1264. @
  1265. text
  1266. @d22 3
  1267. d70 1
  1268. a70 1
  1269. static char     *rcsid="$Id: headers.c,v 1.12 1993/11/05 22:51:53 Aussem Exp Aussem $";
  1270. d950 1
  1271. a950 1
  1272. ** lines longer than 50 chars are continued on another line.
  1273. d985 2
  1274. a986 2
  1275.             /* if the line is greater than 50 columns */
  1276.             if(n > 50) {
  1277. @
  1278.  
  1279.  
  1280. 1.12
  1281. log
  1282. @Return-Receipt-To: recognition now works again
  1283. @
  1284. text
  1285. @d22 3
  1286. d67 1
  1287. a67 1
  1288. static char     *rcsid="$Id: headers.c,v 1.11 1993/11/05 22:22:13 Aussem Exp Aussem $";
  1289. d92 1
  1290. d447 1
  1291. d452 1
  1292. a452 1
  1293.         if(islocal(from, domain, user) || (from_addr != NULL)) {
  1294. d458 4
  1295. d483 1
  1296. a483 1
  1297.          ** flag == 0 while we read the header
  1298. d488 1
  1299. a488 1
  1300.          ** if the header is active and we 
  1301. d490 1
  1302. a490 1
  1303.          ** Whether smail answers the header
  1304. d730 7
  1305. @
  1306.  
  1307.  
  1308. 1.11
  1309. log
  1310. @Return-Receipt-To: recognition now works
  1311. @
  1312. text
  1313. @d22 3
  1314. d64 1
  1315. a64 1
  1316. static char     *rcsid="$Id: headers.c,v 1.10 1993/10/28 23:14:01 Aussem Exp Aussem $";
  1317. d401 1
  1318. d473 13
  1319. a485 1
  1320.          if(receipt) checkheader(buf);
  1321. @
  1322.  
  1323.  
  1324. 1.10
  1325. log
  1326. @space on right of return-receipt headers forgotten
  1327. @
  1328. text
  1329. @d22 3
  1330. d61 1
  1331. a61 1
  1332. static char     *rcsid="$Id: headers.c,v 1.9 1993/10/28 22:05:26 Aussem Exp Aussem $";
  1333. d349 25
  1334. d469 1
  1335. d499 1
  1336. a499 1
  1337. **  Same idea as the old rmail, but also turns user@@domain to domain!user. 
  1338. a677 25
  1339. checkheader(char *buf)
  1340. {
  1341. const char receipt[]="Return-Receipt-To: ";
  1342. const size_t receipt_len=strlen(receipt);
  1343.  
  1344. if(strncmpic(buf,(char *)receipt,receipt_len)==0)
  1345.     {
  1346.     char *r=buf+receipt_len;
  1347.  
  1348.    for(;*r==' ';r++);
  1349.    strcpy(return_receipt,&r[0]);
  1350.    r=strchr(return_receipt,' ');
  1351.    if(r)
  1352.        *r='\0';
  1353.    r=strchr(return_receipt,'\n');
  1354.    if(r)
  1355.        *r='\0';
  1356.    strip_comments(return_receipt);
  1357.     }
  1358. }
  1359.  
  1360. /*
  1361.  *
  1362.  */
  1363. void
  1364. a704 1
  1365.          if(receipt) checkheader(buf);
  1366. @
  1367.  
  1368.  
  1369. 1.9
  1370. log
  1371. @comments from return-receipt removed
  1372. @
  1373. text
  1374. @d22 3
  1375. d58 1
  1376. a58 1
  1377. static char     *rcsid="$Id: headers.c,v 1.8 1993/10/22 00:27:53 Aussem Exp Aussem $";
  1378. d657 2
  1379. d660 3
  1380. @
  1381.  
  1382.  
  1383. 1.8
  1384. log
  1385. @user%site%site.do.main@@sub.do.main
  1386. and
  1387. sub.do.main!site.do.main%site%user
  1388. addresses are now supported
  1389. @
  1390. text
  1391. @d22 6
  1392. d55 1
  1393. a55 1
  1394. static char     *rcsid="$Id: headers.c,v 1.7 1993/10/17 18:44:20 Aussem Exp Aussem $";
  1395. d658 1
  1396. @
  1397.  
  1398.  
  1399. 1.7
  1400. log
  1401. @-f argument is now really used
  1402. smail does not stop on a single dot on a line anymore
  1403. @
  1404. text
  1405. @d22 4
  1406. d49 1
  1407. a49 1
  1408. static char     *rcsid="$Id: headers.c,v 1.6 1993/10/10 21:05:46 Aussem Exp Aussem $";
  1409. d129 1
  1410. d183 36
  1411. d228 2
  1412. a229 1
  1413.     } 
  1414. @
  1415.  
  1416.  
  1417. 1.6
  1418. log
  1419. @continuation lines and whites spaces are now handled in the
  1420. right way
  1421. @
  1422. text
  1423. @d22 4
  1424. d45 1
  1425. a45 1
  1426. static char     *rcsid="$Id: headers.c,v 1.5 1993/10/10 19:32:34 Aussem Exp Aussem $";
  1427. d69 1
  1428. d338 1
  1429. a338 1
  1430.     ** If necessary, copy stdin to a temp file.
  1431. d391 7
  1432. a397 2
  1433.             if((fgets(buf, SMLBUF, stdin) == NULL)
  1434.             || (buf[0] == '.' && buf[1] == '\n')) {
  1435. d407 1
  1436. a407 1
  1437.         (void) fclose(stdin);    /* you don't see this too often! */
  1438. d444 1
  1439. a444 1
  1440. **  and stuffing the actual sending user (the user name on the last From_ 
  1441. d452 6
  1442. a457 2
  1443.         if((fgets(buf, sizeof(buf), stdin) == NULL)
  1444.         || (buf[0] == '.' && buf[1] == '\n')) {
  1445. d461 1
  1446. a461 1
  1447.         if (strncmp("From ", buf, 5) 
  1448. d482 2
  1449. a483 2
  1450. **  Stuff user name into addr, overwriting the user name from previous 
  1451. **  From_ lines, since only the last one counts.  Then rewrite user@@host 
  1452. d515 13
  1453. a527 6
  1454.     if (from[0] == '\0') {
  1455.         char *login;
  1456.         if ((login = getloginname()) == NULL) {
  1457.             (void) strcpy(from, "nobody");    /* bad news */
  1458.         } else {
  1459.             (void) strcpy(from, login);
  1460. a528 2
  1461.     }
  1462.  
  1463. d656 6
  1464. a661 2
  1465.         if((fgets(buf, SMLBUF, stdin) == NULL)
  1466.         || (buf[0] == '.' && buf[1] == '\n')) {
  1467. @
  1468.  
  1469.  
  1470. 1.5
  1471. log
  1472. @Bcc: lines are now supported
  1473. @
  1474. text
  1475. @d22 3
  1476. d41 1
  1477. a41 1
  1478. static char     *rcsid="$Id: headers.c,v 1.4 1993/09/18 20:23:05 Aussem Exp Aussem $";
  1479. d627 9
  1480. @
  1481.  
  1482.  
  1483. 1.4
  1484. log
  1485. @the cc line can now be parsed from cmdline and from file
  1486. @
  1487. text
  1488. @d22 3
  1489. d38 1
  1490. a38 1
  1491. static char     *rcsid="$Id: headers.c,v 1.3 1993/09/18 16:47:47 Aussem Exp Aussem $";
  1492. d60 1
  1493. d85 1
  1494. d649 1
  1495. a649 1
  1496.    /* for the cc-line the field ptr is NULL */
  1497. d678 1
  1498. a678 1
  1499.         if((*s < '!') || (*s > '~')) {
  1500. d680 1
  1501. a680 1
  1502.         }
  1503. d709 1
  1504. a709 1
  1505.          /* To: will be handled differently */
  1506. d711 1
  1507. d828 5
  1508. @
  1509.  
  1510.  
  1511. 1.3
  1512. log
  1513. @insert GNU license text in the header
  1514. @
  1515. text
  1516. @d22 3
  1517. d35 1
  1518. a35 1
  1519. static char     *rcsid="$Id: headers.c,v 1.2 1993/09/11 01:42:43 Aussem Exp Aussem $";
  1520. d66 1
  1521. d80 1
  1522. d644 2
  1523. a645 1
  1524.         if(i->have != 'Y') {
  1525. d705 2
  1526. a706 1
  1527.             if(strncmpic("To:", s, 3) == 0)
  1528. @
  1529.  
  1530.  
  1531. 1.2
  1532. log
  1533. @To: lines will bei insert from mailbody AND cmdline
  1534. EnforcerHits while generation the Cc: line removed
  1535. @
  1536. text
  1537. @d7 14
  1538. d22 4
  1539. d32 1
  1540. a32 1
  1541. static char     *rcsid="$Id: headers.c,v 1.1 1993/09/08 16:27:13 Aussem Exp Aussem $";
  1542. @
  1543.  
  1544.  
  1545. 1.1
  1546. log
  1547. @Initial revision
  1548. @
  1549. text
  1550. @d7 3
  1551. a9 1
  1552.  * $Log$
  1553. d11 1
  1554. d14 1
  1555. a14 1
  1556. static char     *rcsid="$Id$";
  1557. d680 5
  1558. a684 1
  1559.             i->have = 'Y';
  1560. d801 1
  1561. d804 3
  1562. a806 4
  1563.             bol = bol + strlen(bol)-1;
  1564.             bol=rindex(bol,' ');
  1565.             *(bol-1) = '\n';
  1566.             *bol = '\0';
  1567. d819 1
  1568. @
  1569.